package com.rw.coco.data.data.util;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.rw.tool.util.io.file.FileId;
import com.rw.tool.util.io.file.exception.GetPropException;
import com.rw.tool.util.io.file.wrapper.FileQueryWrapper;
import com.rw.tool.util.json.JsonUtil;

import java.util.List;

public class BeanUtil {
    public static FileQueryWrapper getQueryWrapper(Object obj) {
        FileQueryWrapper queryWrapper = new FileQueryWrapper();
        List<BeanPropertyDefinition> properties = getProperties(obj.getClass());
        try {
            for (BeanPropertyDefinition property : properties) {
                Object value = property.getGetter().callOn(obj);
                if (value != null) {
                    queryWrapper.eq(property.getName(), value);
                }
            }
        } catch (Exception e) {
            throw new GetPropException(e);
        }

        return queryWrapper;
    }

    public static FileQueryWrapper getIdWrapper(Object obj) {
        FileQueryWrapper queryWrapper = new FileQueryWrapper();
        List<BeanPropertyDefinition> properties = getProperties(obj.getClass());
        try {
            for (BeanPropertyDefinition property : properties) {
                AnnotatedMethod getter = property.getGetter();
                FileId id = getter.getAnnotation(FileId.class);
                if (id == null) {
                    continue;
                }

                Object value = getter.callOn(obj);
                if (value != null) {
                    queryWrapper.eq(property.getName(), value);
                }
            }
        } catch (Exception e) {
            throw new GetPropException(e);
        }

        return queryWrapper;
    }

    public static <T> T removeIdProp(T obj, Class<T> tClass) {
        List<BeanPropertyDefinition> properties = getProperties(tClass);
        try {
            T newObj = tClass.newInstance();
            for (BeanPropertyDefinition property : properties) {
                AnnotatedMethod getter = property.getGetter();
                FileId id = getter.getAnnotation(FileId.class);
                if (id != null) {
                    continue;
                }

                Object value = getter.callOn(obj);
                property.getSetter().callOnWith(newObj, value);
            }
            return newObj;
        } catch (Exception e) {
            throw new GetPropException(e);
        }
    }

    private static <T> List<BeanPropertyDefinition> getProperties(Class<T> tClass) {
        // 获取mapper，得到javaType
        ObjectMapper mapper = JsonUtil.getMapper();
        JavaType type = mapper.constructType(tClass);

        // 从mapper中取出序列化设置
        SerializationConfig serializationConfig = mapper.getSerializationConfig();
        // 用这个序列化设置解析这个类的信息，并且取出里面的所有属性
        BeanDescription beanDescription = serializationConfig.introspect(type);
        return beanDescription.findProperties();
    }
}
